#!/usr/bin/env python3

'''
Author       : bopo
Date         : 2020-11-19 15:00:48
LastEditors  : bopo
LastEditTime : 2020-12-04 11:29:23
FilePath     : /scripts/ipt5/logs.py
Description  :
'''

import logging
import os
import sys
from logging.handlers import TimedRotatingFileHandler

from unipath import Path

from .config import LOGS_PATH


class Singleton:
    __cls = dict()

    def __init__(self, cls):
        self.__key = cls

    def __call__(self, *args, **kwargs):
        if self.__key not in self.cls:
            self[self.__key] = self.__key(*args, **kwargs)
        return self[self.__key]

    def __setitem__(self, key, value):
        self.cls[key] = value

    def __getitem__(self, item):
        return self.cls[item]

    @property
    def cls(self):
        return self.__cls

    @cls.setter
    def cls(self, cls):
        self.__cls = cls


@Singleton
class Logger:
    def __init__(self, name=None, log_file=None, log_path='.', use_console=False):
        """
        :param level: log level ["NOTSET"|"DEBUG"|"INFO"|"WARNING"|"ERROR"|"CRITICAL"]，default: INFO
        :param name:
        :param log_file:
        :param log_path:
        :param use_console:
        """
        level = 'INFO'
        name = name if name else os.path.split(os.path.splitext(sys.argv[0])[0])[-1]

        log_path = log_path if log_path else LOGS_PATH
        log_file = log_file if log_file else f'{name}.log'
        log_file = Path(log_path, log_file)

        if not level:
            level = self._exec_type()

        self.__logger = logging.getLogger(name)

        self.setLevel(getattr(logging, level.upper()) if hasattr(logging, level.upper()) else logging.INFO)

        if not os.path.exists(log_path):
            os.makedirs(log_path)

        formatter = logging.Formatter("%(asctime)s | %(filename)s | [%(levelname)s] %(message)s", "%Y-%m-%d %H:%M:%S")

        handler_list = list()
        th = TimedRotatingFileHandler(filename=log_file, when='D', backupCount=3, encoding='utf-8')
        th.setFormatter(formatter)
        th.setLevel(logging.INFO)
        handler_list.append(th)

        if use_console:
            handler_list.append(logging.StreamHandler())

        for handler in handler_list:
            handler.setFormatter(formatter)
            self.addHandler(handler)

    def __getattr__(self, item):
        return getattr(self.logger, item)

    def verbose(self, verbose=False):
        level = 'DEBUG' if verbose else 'INFO'
        self.logger.addHandler(logging.StreamHandler())
        self.logger.setLevel(level)

    @property
    def logger(self):
        return self.__logger

    @logger.setter
    def logger(self, func):
        self.__logger = func

    def _exec_type(self):
        return "DEBUG" if os.environ.get("IPYTHONENABLE") else "INFO"


log = Logger()
